//
//      CGE - CRAb Graphics Engine
// 
//      Copyright (C) 2003-2009 by CRAb-UFC
//
//		This file is part of the "CRAb Graphics Engine"
//		See the copyright notice in cge.h for conditions of distribution and use.
//

#ifndef CGE_CLIENTSOCKET_CLASS_H__
#define CGE_CLIENTSOCKET_CLASS_H__

#include "cgeInetAddress.h"

namespace basterd
{
	namespace net
	{
		/** @brief Encapsulates a TCP/IP client Socket.
		 *
		 *  @remarks
		 *		 A socket is an endpoint for communication between two machines connected via TCP
		 * (Transport Control Protocol).
		 *
		 * @see InetAddress, ServerSocket
		 */
		class CGE_API Socket
		{
			// NOTE: a server socket may initialize a child socket for each connected client
			friend class ServerSocket;

			/** 
			 * Private constructor: allowed only for incoming connections to a ServerSocket
			 */
			Socket(__socket sid, __socketAddress& addr );

		public:

			/** 
			 * Default constructor
			 */
			Socket(void);

			/**
			 * Complete constructor
			 *
			 * @param host
			 * @param port
			 */
			Socket(const String& host, unsigned short port);

			/**
			 *  Destructor.
			 */
			virtual ~Socket(void);


			/**
			 * Gets the internal socket ID.
			 */
			__socket getSocketId(void) const
			{
				return socketId;
			}

			/**
			 * Checks whether this socket is connected or not.
			 */
			bool isConnected(void) const;

			/**
			 * Connects to a remote host
			 *
			 * @param host IP address of the remote host, or its DNS name
			 * @param port Port used to connect to the remote host. Ranges from 0 to 65535.
			 */
			bool connect(const String& host, unsigned short port);

			/**
			 * Closes this socket. Safe amongst many calls.
			 */
			void close(void) const;

			/**
			 *  Sends a buffer containing data using this socket.
			 */
			int    send( const void* data, size_t sizeInBytes ) const;
			
			/**
			 *  Receives a data block from this socket.
			 */
			int receive( void* data, size_t sizeInBytes ) const;

			/**
			 *  Receives a null-terminated string from this socket.
			 */
			int receive( String& str ) const;

			/**
			 *  Writes a null-terminated string to this socket's output stream.
			 */
			int send( const String& str ) const;
			
			/**
			 * Disables subsequent socket send, receive or both, operations on a socket, depending on the value of the how argument. 
			 * 
			 * @param __socket A descriptor identifying a socket
			 * @param      how Specifies the file descriptor of the socket.
			 */
			bool shutdown(__socket socket, int how);

			/**
			 * Access the destination port assigned to this socket.
			 */
			unsigned short getPort(void) const;

			/**
			 * 	Access the destination address assigned to this socket
			 */
			const String& getHostAddress(void) const;

			/**
			 *  Gets the name and port of the computer at the other end of this connection.
			 *
			 *  @return A string containing the name and port. Example: "192.168.1.12:8080".
			 *          An empty string is returned when an error occurs.
			 */
			String getPeerName(void) const;

			/**
			 *  Gets the name of the computer that your program is running on.
			 *  An empty string is returned when an error occurs.
			 */
			String getHostName(void) const;

		private:

			/**
			 * Copy-constructor: not allowed
			 */
			Socket( const Socket& );
			/**
			 * Assignment operator: not allowed
			 */
			Socket& operator = ( const Socket& );
			
			/**
			 * Holds the address bound to this socket.
			 */
			String  hostAddress;

			/**
			 * Address bound to this TCP socket.
			 */
			__socketAddress address;

			/**
			 * Internal socket
			 */
			__socket socketId;

			/**
			 * Holds the port bound to this socket.
			 */
			unsigned short port;

			/**
			 * Flag indicating whether this socket is connected or not.
			 */
			mutable bool connected;

			/**
			 * Internal method responsible for initialize the socket.
			 */
			bool create(void);

			/**
			 * Internal method responsible for binding this socket to the given port.
			 *
			 * @param port
			 */
			bool bind(const int port);			

		}; // end of the Socket class

		/// For ease of coding, defines a TcpSocket type
		typedef Socket TcpSocket;
	}
}



#endif // CGE_SERVER_CLASS_H__
